<template>
  <div class="tree-container">
    <q-input v-model="searchText" placeholder="🔍 搜索图层" />
    <draggable
      :list="filteredLayers"
      group="layers"
      @end="onDragEnd"
      item-key="id"
      handle=".drag-handle"
    >
      <template #item="{ element }">
        <div class="layer-item" @contextmenu.prevent="showContextMenu(element)">
          <span class="drag-handle"><q-icon name="drag_indicator" /></span>
          <span
            class="layer-type"
            :class="getTypeIcon(element.type)"
            @mouseover="hoveredLayer = element"
            @mouseleave="hoveredLayer = null"
            >{{ getTypeName(element.type) }}</span
          >
          <input
            v-if="renamingLayer === element"
            type="text"
            v-model="element.name"
            @blur="stopRenaming"
            @keydown.enter="stopRenaming"
            ref="renameInput"
          />
          <span v-else>{{ element.name }}</span>
          <span class="layer-actions">
            <q-icon name="visibility" @click="toggleVisibility(element)" />
            <q-icon name="lock" @click="toggleLock(element)" />
          </span>
          <nested-draggable-tree
            v-if="element.children && element.children.length > 0"
            :layers="element.children"
          />
        </div>
      </template>
    </draggable>

    <!-- Context Menu -->
    <q-menu context-menu touch-position>
      <q-list dense style="min-width: 100px">
        <q-item clickable @click="startRenaming(selectedLayer)">
          <q-item-section>重命名</q-item-section>
        </q-item>
        <q-item clickable @click="copyLayer(selectedLayer)">
          <q-item-section>复制</q-item-section>
        </q-item>
        <q-item clickable @click="pasteLayer()">
          <q-item-section>粘贴</q-item-section>
        </q-item>
      </q-list>
    </q-menu>

    <!-- Type Tooltip -->
    <q-tooltip v-if="hoveredLayer" anchor="top middle" self="bottom middle">
      {{ getTypeDescription(hoveredLayer.type) }}
    </q-tooltip>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watch, shallowRef } from "vue";
import draggable from "vuedraggable";

export default defineComponent({
  name: "NestedDraggableTree",
  components: {
    draggable,
    NestedDraggableTree: shallowRef(() => import("./NestedDraggableTree.vue")),
  },
  props: {
    layers: {
      type: Array as () => any[],
      required: true,
    },
  },
  setup(props) {
    const searchText = ref("");
    const hoveredLayer = ref(null);
    const renamingLayer = ref(null);
    const selectedLayer = ref(null);
    const copiedLayer = ref(null);

    const filteredLayers = ref(props.layers);

    watch(searchText, (newSearchText) => {
      if (!newSearchText) {
        filteredLayers.value = props.layers;
        return;
      }
      filteredLayers.value = searchInTree(
        props.layers,
        newSearchText.toLowerCase()
      );
    });

    const onDragEnd = () => {
      console.log("Drag ended");
    };

    const showContextMenu = (layer: any) => {
      selectedLayer.value = layer;
    };

    const startRenaming = (layer: any) => {
      renamingLayer.value = layer;
    };

    const stopRenaming = () => {
      renamingLayer.value = null;
    };

    const copyLayer = (layer: any) => {
      copiedLayer.value = { ...layer };
    };

    const pasteLayer = () => {
      if (copiedLayer.value) {
        const newLayer = {
          ...copiedLayer.value,
          id: Date.now(),
          name: `${copiedLayer.value.type} ${props.layers.length + 1}`,
        };
        props.layers.push(newLayer);
        filteredLayers.value = props.layers;
      }
    };

    const toggleVisibility = (layer: any) => {
      layer.visible = !layer.visible;
    };

    const toggleLock = (layer: any) => {
      layer.locked = !layer.locked;
    };

    const getTypeIcon = (type: string) => {
      switch (type) {
        case "container":
          return "folder";
        case "component":
          return "widgets";
        case "shape":
          return "crop_square";
        case "text":
          return "text_fields";
        case "chart":
          return "bar_chart";
        default:
          return "";
      }
    };

    const getTypeName = (type: string) => {
      return type.charAt(0).toUpperCase() + type.slice(1);
    };

    const getTypeDescription = (type: string) => {
      switch (type) {
        case "container":
          return "容器";
        case "component":
          return "组件";
        case "shape":
          return "形状";
        case "text":
          return "文字";
        case "chart":
          return "图表";
        default:
          return "";
      }
    };

    const searchInTree = (nodes: any[], query: string): any[] => {
      let results: any[] = [];
      nodes.forEach((node) => {
        if (node.name.toLowerCase().includes(query)) {
          results.push(node);
        }
        if (node.children && node.children.length > 0) {
          const childrenResults = searchInTree(node.children, query);
          if (childrenResults.length > 0) {
            results.push({ ...node, children: childrenResults });
          }
        }
      });
      return results;
    };

    return {
      searchText,
      hoveredLayer,
      renamingLayer,
      selectedLayer,
      filteredLayers,
      onDragEnd,
      showContextMenu,
      startRenaming,
      stopRenaming,
      copyLayer,
      pasteLayer,
      toggleVisibility,
      toggleLock,
      getTypeIcon,
      getTypeName,
      getTypeDescription,
    };
  },
});
</script>

<style scoped>
.tree-container {
  padding: 16px;
}

.layer-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px;
  border-bottom: 1px solid #eee;
}

.drag-handle {
  cursor: move;
  margin-right: 8px;
}

.layer-type {
  cursor: pointer;
}

.layer-actions .q-icon {
  margin-left: 8px;
  cursor: pointer;
}
</style>
